perm filename DV.DIF[MF,ALS]1 blob sn#776770 filedate 1984-11-28 generic text, type T, neo UTF8
  1) DV3.WEB[MF,ALS] and 2) DV.WEB[MF,ALS]	11-28-84 08:35	pages 1,1

**** File 1) DV3.WEB[MF,ALS]/1P/6L
1)	C00016 00004	@* The character set.
1)	C00024 00005	@* Device-independent file format.
1)	C00063 00006	@* The imPRESS file format.
1)	C00080 00007	@* Input from binary files.
1)	C00094 00008	@* GF file format.
1)	C00121 00009	@* Reading the font information.
1)	C00140 00010	@* Optional modes of output.
1)	C00156 00011	@* Defining fonts.
1)	C00166 00012	@* Low level output routines.
1)	C00168 00013	@* Translation to symbolic form.
1)	C00195 00014	@* Skipping pages.
1)	C00199 00015	@* Using the backpointers.
1)	C00204 00016	@* Reading the postamble.
1)	C00210 00017	@* The main program.
1)	C00216 00018	@* System-dependent changes.
1)	C00217 00019	@* Index.
1)	C00218 ENDMK
1)	C⊗;
**** File 2) DV.WEB[MF,ALS]/1P/6L
2)	C00017 00004	@* The character set.
2)	C00025 00005	@* Device-independent file format.
2)	C00064 00006	@* The imPRESS file format.
2)	C00081 00007	@* Input from binary files.
2)	C00095 00008	@* GF file format.
2)	C00122 00009	@* Reading the font information.
2)	C00146 00010	@* Optional modes of output.
2)	C00162 00011	@* Defining fonts.
2)	C00172 00012	@* Low level output routines.
2)	C00174 00013	@* Translation to symbolic form.
2)	C00201 00014	@* Skipping pages.
2)	C00205 00015	@* Using the backpointers.
2)	C00210 00016	@* Reading the postamble.
2)	C00216 00017	@* The main program.
2)	C00222 00018	@* System-dependent changes.
2)	C00223 00019	@* Index.
2)	C00224 ENDMK
2)	C⊗;
***************


**** File 1) DV3.WEB[MF,ALS]/3P/67L
1)	@p program DVI_IMAGEN(@!dvi_file,@!output);
**** File 2) DV.WEB[MF,ALS]/3P/67L
2)	@d abort(#)==begin print(' ',#); jump_out;
2)			end
2)	@d bad_gf(#)==abort('Bad GF file: ',#,'!')
2)	@.Bad GF file@>
  1) DV3.WEB[MF,ALS] and 2) DV.WEB[MF,ALS]	11-28-84 08:35	pages 3,3

2)	@p procedure jump_out;
2)	begin goto final_end;
2)	end;
2)	@p program DVI_IMAGEN(@!dvi_file,@!output);
***************


**** File 1) DV3.WEB[MF,ALS]/3P/100L
1)	@ Here are some macros for common programming idioms. We will have occasion,
**** File 2) DV.WEB[MF,ALS]/3P/108L
2)	@!max_glyph_no=127; {largese allowed glyph number}
2)	@ Here are some macros for common programming idioms. We will have occasion,
***************


**** File 1) DV3.WEB[MF,ALS]/9P/66L
1)	@ Here is a procedure that absorbs the necessary information from a
1)	\.{GF} file, assuming that the file has just been successfully reset
1)	so that we are ready to read its first byte.
1)	The procedure does not check the \.{GF} file
1)	for validity, nor does it give explicit information about what is
1)	wrong with a \.{GF} file that proves to be invalid; \.{DVIIMAGEN} 
1)	need not do this, since \.{GF} files are almost always valid,
1)	and since the \.{GFtype} utility program has been specifically designed
**** File 2) DV.WEB[MF,ALS]/9P/66L
2)	@ We will need a number of procedures to extract the necessary inforation
2)	fron a
2)	\.{GF} file, assuming that the file has just been successfully reset
2)	so that we are ready to read its first byte.
2)	Only a limited amount of validity checking of the \.{GF} file will be done 
2)	since \.{GF} files are almost always valid,
2)	and since the \.{GFtype} utility program has been specifically designed
***************


**** File 1) DV3.WEB[MF,ALS]/9P/77L
1)	There is a parameter, |z|, which represents the scaling factor being
1)	used to compute the font dimensions; it must be in the range $0<z<2↑{27}$.
1)	@p function in_gf(@!z:integer):boolean; {input \.{GF} data or return |false|}
**** File 2) DV.WEB[MF,ALS]/9P/76L
2)	Since we are going to defer the creation of an \.{imPRESS} |bgly|
2)	command for each glyph until the first time that it is actually called, we
2)	will now only decypher the |gf| commands far enough to determine if they
2)	are to be saved and to store them away in as compact a form as possible.
2)	Character width information,
2)	read from the |gf_postamble|, will be stored in a |width| table and
2)	indexed via a |width_base| array for the character's width in \.{DVI}
2)	units, and in a |pixel_width| table for the |device_width| values.
  1) DV3.WEB[MF,ALS] and 2) DV.WEB[MF,ALS]	11-28-84 08:35	pages 9,9

2)	By way of contrast, the raster information will be
2)	only slightly modifed before storage in a large |m_store| array.
2)	@p procedure find_gf_postamble;
2)	var q,@!k: integer;
2)	begin
2)	gf_post_loc←gf_length-4;
2)	repeat if gf_post_loc=0 then bad_gf('all 223s');
2)	@.all 223s@>
2)	move_to_gf_byte(gf_post_loc); k←gf_byte; decr(gf_post_loc);
2)	until k≠223;
2)	if k≠gf_id_byte then bad_gf('ID byte is ',k:1);
2)	@.ID byte is wrong@>
2)	move_to_gf_byte(gf_post_loc-3); q←gf_signed_quad;
2)	if (q<0)∨(q>gf_post_loc-3) then bad_gf('gf_post pointer ',q:1,' at byte ',gf_post_loc-3:1);
2)	@.gf_post pointer is wrong@>
2)	move_to_gf_byte(q); k←gf_byte;
2)	if k≠gf_post then bad_gf('byte ',q:1,' is not gf_post');
2)	@.byte n is not gf_post@>
2)	end;
2)	@ Reading the postamble.
2)	Having located the |gf_postamble| we must read it and save the information
2)	that we will need to pass on to the \.{imPRESS} file, glyph by glyph, in 
2)	|bgly| commands, on the first occasion that any particular glyph is
2)	requested by the \.{.DVI} file.
2)	@ Here is the main information we glean from the postamble together with
2)	some auxiliary parameters.
2)	@<Glob...@>=
2)	@!design_size: integer;
2)	@!hppp, @!vppp: integer;
2)	@!check_sum: integer;
2)	@!gf_post_loc: integer;
2)	@!magnification: real;
2)	@!tfm_width: array [0..max_glyph_no] of integer;
2)	@!device_width: array [0..max_glyph_no] of integer;
2)	@!min_x, @!max_x, @!min_y, @!max_y: integer; {bounds of the current subarray}
2)	@!min_x_stated, @!max_x_stated, @!min_y_stated, @!max_y_stated: integer;
2)		{bounds stated in the \.{GF} file}
2)	@!min_x_box, @!max_x_box, @!min_y_box, @!max_y_box: integer;
2)		{bounds observed in the entire file so far}
2)	@ When we get to the present code, the |post_post| command has
2)	just been read.
2)	@<Make sure that the end of the file is well-formed@>=
2)	if k≠post_post then
2)		error('should be postpost!');
2)	@.should be postpost@>
2)	q←gf_signed_quad;
2)	if q≠gf_post_loc then
2)		error('postamble pointer should be ',gf_post_loc:1,' not ',q:1);
  1) DV3.WEB[MF,ALS] and 2) DV.WEB[MF,ALS]	11-28-84 08:35	pages 9,9

2)	@.postamble pointer should be...@>
2)	m←gf_byte;
2)	if m≠gf_id_byte then error('identification byte should be ',gf_id_byte:1);
2)	@.identification byte should be n@>
2)	k←cur_gf_loc; m←223;
2)	while (m=223)∧ not eof(gf_file) do m←gf_byte;
2)	if not eof(gf_file) then bad_gf('signature in byte ',cur_gf_loc-1:1,
2)	@.signature...should be...@>
2)			' should be 223')
2)	else if cur_gf_loc<k+4 then
2)		error('not enough signature bytes at end of file');
2)	@.not enough signature bytes...@>
2)	@#
2)	procedure read_gf_postamble;
2)	var k:integer; {loop index}
2)	@!p,@!q,@!m,@!c:integer; {general purpose registers}
2)	begin gf_post_loc←cur_gf_loc-1;
2)	@.gf_postamble starts at byte n@>
2)	p←gf_signed_quad;
2)	design_size←gf_signed_quad; check_sum←gf_signed_quad;@/
2)	hppp←gf_signed_quad; vppp←gf_signed_quad;@/
2)	magnification←hppp/(65536.0*resolution/72.27);
2)	oc_mag←round(1000*magnification);
2)	min_x←gf_signed_quad; max_x←gf_signed_quad;
2)	min_y←gf_signed_quad; max_y←gf_signed_quad;@/
2)	@<Process the character locations in the postamble@>;
2)	@<Make sure that the end of the file is well-formed@>;
2)	end;
2)	@ Now here is the main function that processes the information from the } file.
2)	@p function in_gf(@!z:integer):boolean; {input \.{GF} data or return |false|}
***************


**** File 1) DV3.WEB[MF,ALS]/9P/89L
1)	begin @<Read past the header data; |goto 9997| if there is a problem@>;
1)	@<Store character-width indices at the end of the |width| table@>;
1)	@<Read and convert the width values, setting up the |in_width| table@>;
1)	@<Move the widths from |in_width| to |width|, and append |pixel_width| values@>;
1)	width_ptr←wp; in_gf←true; goto 9999;
1)	9997: print_ln('---not loaded, GF file is bad');
**** File 2) DV.WEB[MF,ALS]/9P/178L
2)	begin
2)	print_ln('entering in-gf for font ',f:1);
2)	find_gf_postamble;
2)	read_gf_postamble; print_ln('postamble read');
2)	@<Process the gf_preamble@>;
2)	@<Stow all the characters@>;
2)	 in_gf←true; goto 9999;
  1) DV3.WEB[MF,ALS] and 2) DV.WEB[MF,ALS]	11-28-84 08:35	pages 9,9

2)	9997: print_ln('---not loaded, GF file is bad');
***************


**** File 1) DV3.WEB[MF,ALS]/9P/99L
1)	@ @<Read past the header...@>=
1)	@ @<Store character-width indices...@>=
1)	@ The most important part of |in_gf| is the width computation, which
**** File 2) DV.WEB[MF,ALS]/9P/190L
2)	@ @<Process the character locations...@>=
2)	repeat k←gf_byte;
2)	if k=char_loc then begin
2)		c←first_gf_par(k);
2)		if c>max_glyph_no then abort('Character number too large');
2)		device_width[c]←gf_signed_quad;
2)		tfm_width[c]←gf_signed_quad;
2)		p←gf_signed_quad;
2)		k←gf_nop;
2)		end;
2)	until k≠gf_nop;
2)	@ @<Process the gf_preamble@>=
2)	open_gf_file;
2)	o←gf_byte; {fetch the first byte}
2)	if o≠pre then bad_gf('First byte isn''t start of gf_preamble!');
2)	@.First byte isn't...@>
2)	o←gf_byte; {fetch the identification byte}
2)	if o≠gf_id_byte then
2)		error('identification byte should be ',gf_id_byte:1,
2)		' not ',o:1,'!');
2)	@.identification byte should be n@>
2)	o←gf_byte; {fetch the length of the introductory comment}
2)	while o>0 do
2)		begin decr(o); b←gf_byte;
2)		end;
2)	print_ln('ready to translate all characters');
2)	@ @<Stow all...@>=
2)	repeat gf_prev_ptr←cur_gf_loc;
2)		@<Pass |gf_nop|, |gf_xxx| and |yyy| commands@>;
2)		if o≠post then
2)			begin if o≠boc then
2)				bad_gf('byte ',cur_gf_loc-1:1,' is not boc (',o:1,')');
2)			print(cur_gf_loc:1);
2)			print(' [');
2)			@<Pass a |boc| command@>;
2)			if not do_char then bad_gf('char ended unexpectedly');
2)			@<Pass an |eoc| command@>;
2)	{|            tabulate;|} {here if desired}
2)			print(']');
  1) DV3.WEB[MF,ALS] and 2) DV.WEB[MF,ALS]	11-28-84 08:35	pages 9,9

2)			end;
2)	until o=post;
2)	@ @<Pass |gf_nop|, |gf_xxx| and |yyy| commands@>=
2)	repeat
2)		a←cur_gf_loc;
2)		o←gf_byte; p←first_gf_par(o);
2)		if eof(gf_file) then bad_gf('the file ended prematurely');
2)	@.the |gf| file ended prematurely@>
2)		if o=yyy then o←gf_nop
2)		else if (o≥gf_xxx1) and (o≤gf_xxx1+3) then
2)		  begin
2)		  while p>0 do
2)		    begin
2)		    q←gf_byte; decr(p); {these are all ignored}
2)		    end;
2)	@ @<Pass a |boc|...@>=
2)	incr(total_chars);
2)	char_code←gf_signed_quad;
2)	p←gf_signed_quad;
2)	c←char_code mod 256;
2)	if c<0 then c←c+256;
2)	print(c:1);
2)	if char_code≠c then
2)		print(' in family ',(char_code-c) div 256 : 1);
2)	min_x_stated←gf_signed_quad; max_x_stated←gf_signed_quad;
2)	min_y_stated←gf_signed_quad; max_y_stated←gf_signed_quad;
2)	z←gf_signed_quad;
2)	z←z-min_x_stated;
2)	if char_ptr[c]≠p then
2)		error('previous character pointer should be ',char_ptr[c]:1,
2)			', not ',p:1,'!');
2)	char_ptr[c]←gf_prev_ptr;
2)	width←max_x-min_x+1; bytes_required←(width+7) div 8;
2)	glyph_pointers[f,c]←s_i;
2)	a=f*128+c; stow_signed_pair(a); {family and member assuming rotation always zero}
2)	stow_signed_pair(device_width[c]);
2)	stow_signed_pair(max_x_stated-min_x_stated+1);
2)	stow_signed_pair(min_x_stated);
2)	stow_signed_pair(max_y_stated-min_y_stated+1);
2)	stow_signed_pair(max_y_stated);
2)	if z≤166 then stow_byte(n_row+z) else
2)		begin
2)		stow_byte(new_row); stow_byte(z div 256); stow_byte(z mod 256);
2)		end;
2)	n_r_flag←true;
2)	 	  o←gf_nop;
2)		  end;
2)	until o≠gf_nop;
  1) DV3.WEB[MF,ALS] and 2) DV.WEB[MF,ALS]	11-28-84 08:35	pages 9,9

2)	@ @<Pass an |eoc|...@>=
2)	There is a parameter, |z|, which represents the scaling factor being
2)	used to compute the font dimensions; it must be in the range $0<z<2↑{27}$.
2)	@ The most important part of |in_gf| is the width computation, which
***************


**** File 1) DV3.WEB[MF,ALS]/9P/130L
1)	@<Read and convert the width values...@>=
1)	@<Replace |z| by $|z|↑\prime$ and compute $\alpha,\beta$@>;
1)	@ @<Replace |z|...@>=
1)	begin alpha←16*z; beta←16;
1)	while z≥@'40000000 do
1)		begin z←z div 2; beta←beta div 2;
1)		end;
1)	end
1)	@ A \.{DVI}-reading program usually works with font files instead of
**** File 2) DV.WEB[MF,ALS]/9P/317L
2)	@ A \.{DVI}-reading program usually works with font files instead of
***************


**** File 1) DV3.WEB[MF,ALS]/13P/134L
1)	@ Commands are broken down into ``major'' and ``minor'' categories:
1)	A major command is always shown in full, while a minor one is
1)	put into the buffer in abbreviated form. Minor commands, which
1)	account for the bulk of most \.{DVI} files, involve horizontal spacing
1)	and the typesetting of characters in a line; these are shown in full
1)	only if |out_mode≥verbose|.
1)	@d show(#)==begin flush_text; showing←true; print(a:1,': ',#);
1)		end
1)	@d major(#)==if out_mode>errors_only then show(#)
1)	@d minor(#)==if out_mode≥verbose then
1)		begin showing←true; print(a:1,': ',#);
1)		end
1)	@d error(#)==if not showing then show(#) else print(' ',#)
1)	@<Translate the next command...@>=
1)	begin a←cur_loc; showing←false;
**** File 2) DV.WEB[MF,ALS]/13P/134L
2)	@ @<Translate the next command...@>=
2)	begin a←cur_loc; showing←false;
***************